package utils;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingQueue;

public class LRUCache<K, V> extends LinkedHashMap<K, V> {

    private LinkedBlockingQueue<K> removalQueue = new LinkedBlockingQueue(5);

    // 初始容量
    private static final int INITIAL_CAPACITY = 16;

    private static final float LOAD_FACTOR = 0.75F;

    private int mCacheSize;

    /**
     * 构造方法
     *
     * @param cacheSize 缓存大小
     */
    public LRUCache(int cacheSize) {
        // 参数accessOrder -> false 基于插入顺序, true 基于访问顺序, get一个元素后，这个元素被自动加到最后
        super(INITIAL_CAPACITY, LOAD_FACTOR, true);
        mCacheSize = cacheSize;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        // 当size大于缓存大小时，返回true会自动删除最少使用的数据
        boolean isNeedRemove = size() > mCacheSize;
        if (isNeedRemove) {
            try {
                removalQueue.put(eldest.getKey());
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        return isNeedRemove;
    }

    /**
     * 获取自动删除的元素
     *
     * @return 自动删除的元素
     */
    public K getFirstKey() {
        return removalQueue.poll();
    }


    public static void main(String[] args) {
        LRUCache LRUCache = new LRUCache(3);
        LRUCache.put("a", 1);
        LRUCache.put("b", 2);
        LRUCache.put("c", 3);

        System.out.println(LRUCache.get("a"));

        LRUCache.put("d", 5);
        LRUCache.put("f", 5);
        LRUCache.put("g", 5);
        LRUCache.put("h", 5);
        LRUCache.put("i", 5);
        LRUCache.put("j", 5);
        LRUCache.put("k", 5);

        System.out.println(LRUCache.getFirstKey());

        System.out.println(LRUCache);


    }
}
